/**
 * 
 */
package controller;

import components.Util;
import components.exceptions.BinaryToIntException;
import components.exceptions.IntToBinaryException;
import components.register.RegisterGroup;

import controller.notify.Notify;

/**
 * @author Chz
 * 
 */
public class PCController extends Controller {
	private static PCController self;
	private Notify notify = null;

	private PCController() {
	}

	public static PCController getInstance() {
		if (self == null)
			self = new PCController();

		return self;
	}

	public synchronized void notify(Notify n) {
		this.notify = n;
	}

	public void run() {
		int pc = 0;
		try {
			pc = Util.binaryToInt(regs.getPC());
		} catch (BinaryToIntException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		switch (notify.getType()) {
		case Notify.DONE:
			// execution of the instruction finished, pc=pc+1
			pc++;
			try {
				regs.setPC(Util.intToBinary(pc, RegisterGroup.PC_LEN));
			} catch (IntToBinaryException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			break;

		case Notify.NOINC:
			// this instruction changed PC manually
			break;

		default:
			System.err.println("fatal error in PC, undefined Notify type "
					+ "received!!!!!!!!!!!!!!!!");

		}

		bus.sendNotify(new Notify(Notify.FETCH), MemoryController.getInstance());
	}
}
